package com.cnpc.fyupdate.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

import com.cnpc.fyupdate.R;
import com.cnpc.fyupdate.download.DownInfo;
import com.cnpc.fyupdate.download.DownState;
import com.cnpc.fyupdate.download.HttpDownManager;
import com.cnpc.fyupdate.listener.HttpDownOnNextListener;
import com.cnpc.fyupdate.utils.AppUtil;
import com.cnpc.fyupdate.utils.DbDownUtil;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import rx.Observable;
import rx.Observer;

/**
 * Created by bingju on 2017/1/23.
 * 多任务下载更新apk服务
 */

public class UpdateService extends Service{
    List<DownInfo> listData;
    DbDownUtil dbUtil;
//    ProgressDialog progressDialog;
    private HttpDownManager manager;

    private static final Class<?>[] mSetForegroundSignature = new Class[] {
            boolean.class};
    private static final Class<?>[] mStartForegroundSignature = new Class[] {
            int.class, Notification.class};
    private static final Class<?>[] mStopForegroundSignature = new Class[] {
            boolean.class};

    private NotificationManager mNotificationManager;
    NotificationCompat.Builder mBuilder;
    private Method mSetForeground;
    private Method mStartForeground;
    private Method mStopForeground;
    private Object[] mSetForegroundArgs = new Object[1];
    private Object[] mStartForegroundArgs = new Object[2];
    private Object[] mStopForegroundArgs = new Object[1];

    private boolean mReflectFlg = false;

    private static final int NOTIFICATION_ID = 1; // 如果id设置为0,会导致不能设置为前台service

    @Override
    public void onCreate() {
        super.onCreate();
    }

    private void initResource() {
        dbUtil= DbDownUtil.getInstance();
        manager= HttpDownManager.getInstance();
        listData=dbUtil.queryDownAll();
        /*第一次模拟服务器返回数据掺入到数据库中*/
        if(listData.isEmpty()){
            String[] downUrl=new String[]{"http://www.izaodao.com/app/izaodao_app.apk",
                    "http://download.fir.im/v2/app/install/572eec6fe75e2d7a05000008?download_token=572bcb03dad2eed7c758670fd23b5ac4"};
            for (int i = 0; i < downUrl.length; i++) {
//                File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
//                        "test"+i + ".apk");
                File outputFile = new File(AppUtil.initAPKDir(this),"test"+i+".apk");
                DownInfo apkApi=new DownInfo(downUrl[i]);
                apkApi.setId(i);
                apkApi.setState(DownState.START);
                apkApi.setSavePath(outputFile.getAbsolutePath());
                dbUtil.save(apkApi);
            }
            listData=dbUtil.queryDownAll();
        }
        loadData(listData);
    }
    private void loadData(List<DownInfo> listData) {
        Observable.from(listData)
                .first()
                .subscribe(new Observer<DownInfo>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(DownInfo downInfo) {
                        downInfo.setListener(httpProgressOnNextListener);
                        manager.startDown(downInfo);
                    }
                });
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        initResource();
        initView();
        return START_STICKY;
    }

    private void initView() {
//        progressDialog = new ProgressDialog();
//        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//        progressDialog.setMax(100);
//        progressDialog.setCancelable(false);
//        progressDialog.show();
    }
    /**
     * 方法描述：createNotification方法
     * @param
     * @return
     * @see     UpdateService
     */
    public void createNotification() {
        try {
            mStartForeground = UpdateService.class.getMethod("startForeground", mStartForegroundSignature);
            mStopForeground = UpdateService.class.getMethod("stopForeground", mStopForegroundSignature);
        } catch (NoSuchMethodException e) {
            mStartForeground = mStopForeground = null;
        }

        try {
            mSetForeground = getClass().getMethod("setForeground",
                    mSetForegroundSignature);
        } catch (NoSuchMethodException e) {
            throw new IllegalStateException(
                    "OS doesn't have Service.startForeground OR Service.setForeground!");
        }
        Bitmap btm = BitmapFactory.decodeResource(getResources(),
                R.drawable.fioylogo);
//				new NotificationCompat.Builder(MainActivity.this).
        mBuilder = new NotificationCompat.Builder(
                UpdateService.this).setSmallIcon(R.drawable.fioylogo)
                .setContentTitle("正在下载")
                .setContentText("已下载");
        mBuilder.setTicker(getString(R.string.app_name) + "开始下载");//第一次提示消息的时候显示在通知栏上
        mBuilder.setNumber(0);
        mBuilder.setProgress(0, 0, false);//设置为true，表示流动
//        mBuilder.setLargeIcon(btm);
        mBuilder.setAutoCancel(true);
        // 将Ongoing设为true 那么notification将不能滑动删除
        mBuilder.setOngoing(false);

        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(0, mBuilder.build());
//        startForegroundCompat(NOTIFICATION_ID, mBuilder.build());
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }
    /*下载回调*/
    HttpDownOnNextListener<DownInfo> httpProgressOnNextListener=new HttpDownOnNextListener<DownInfo>() {
        @Override
        public void onNext(DownInfo baseDownEntity) {
//            progressDialog.setMessage("提示：下载完成");
            openFile(new File(baseDownEntity.getSavePath()));
        }

        @Override
        public void onStart() {
//            progressDialog.setMessage("提示:开始下载");
            createNotification();
        }

        @Override
        public void onComplete() {
            mBuilder.setContentText("下载完成");
            mBuilder.setProgress(100, 100, false);
            mNotificationManager.notify(0, mBuilder.build());
            mNotificationManager.cancel(0);
        }

        @Override
        public void onError(Throwable e) {
            super.onError(e);
            mBuilder.setContentText("下载失败");
            mBuilder.setProgress(100, 100, false);
            mNotificationManager.notify(0, mBuilder.build());
        }


        @Override
        public void onPuase() {
            super.onPuase();
            mBuilder.setContentText("暂停");
        }

        @Override
        public void onStop() {
            super.onStop();
        }

        @Override
        public void updateProgress(long readLength, long countLength) {
            mBuilder.setContentText("已下载"+(countLength <= 0 ? 0 : (int) ((readLength * 100) / countLength)) + "%");
            mBuilder.setProgress(100, countLength <= 0 ? 0 : (int) ((readLength * 100) / countLength), false);
            mNotificationManager.notify(0, mBuilder.build());
//            progressDialog.setMessage("提示:下载中");
//            progressDialog.setMax((int) countLength);
//            progressDialog.setProgress((int) readLength);
        }
    };

    void invokeMethod(Method method, Object[] args) {
        try {
            method.invoke(this, args);
        } catch (InvocationTargetException e) {
            // Should not happen.
            Log.w("ApiDemos", "Unable to invoke method", e);
        } catch (IllegalAccessException e) {
            // Should not happen.
            Log.w("ApiDemos", "Unable to invoke method", e);
        }
    }

    /**
     * This is a wrapper around the new startForeground method, using the older
     * APIs if it is not available.
     */
    void startForegroundCompat(int id, Notification notification) {
        if (mReflectFlg) {
            // If we have the new startForeground API, then use it.
            if (mStartForeground != null) {
                mStartForegroundArgs[0] = Integer.valueOf(id);
                mStartForegroundArgs[1] = notification;
                invokeMethod(mStartForeground, mStartForegroundArgs);
                return;
            }

            // Fall back on the old API.
            mSetForegroundArgs[0] = Boolean.TRUE;
            invokeMethod(mSetForeground, mSetForegroundArgs);
            mNotificationManager.notify(id, notification);
        } else {
            /* 还可以使用以下方法，当sdk大于等于5时，调用sdk现有的方法startForeground设置前台运行，
             * 否则调用反射取得的sdk level 5（对应Android 2.0）以下才有的旧方法setForeground设置前台运行 */

            if(Build.VERSION.SDK_INT >= 5) {
                startForeground(id, notification);
            } else {
                // Fall back on the old API.
                mSetForegroundArgs[0] = Boolean.TRUE;
                invokeMethod(mSetForeground, mSetForegroundArgs);
                mNotificationManager.notify(id, notification);
            }
        }
    }

    /**
     * This is a wrapper around the new stopForeground method, using the older
     * APIs if it is not available.
     */
    void stopForegroundCompat(int id) {
        if (mReflectFlg) {
            // If we have the new stopForeground API, then use it.
            if (mStopForeground != null) {
                mStopForegroundArgs[0] = Boolean.TRUE;
                invokeMethod(mStopForeground, mStopForegroundArgs);
                return;
            }

            // Fall back on the old API.  Note to cancel BEFORE changing the
            // foreground state, since we could be killed at that point.
            mNotificationManager.cancel(id);
            mSetForegroundArgs[0] = Boolean.FALSE;
            invokeMethod(mSetForeground, mSetForegroundArgs);
        } else {
            /* 还可以使用以下方法，当sdk大于等于5时，调用sdk现有的方法stopForeground停止前台运行，
             * 否则调用反射取得的sdk level 5（对应Android 2.0）以下才有的旧方法setForeground停止前台运行 */

            if(Build.VERSION.SDK_INT >= 5) {
                stopForeground(true);
            } else {
                // Fall back on the old API.  Note to cancel BEFORE changing the
                // foreground state, since we could be killed at that point.
                mNotificationManager.cancel(id);
                mSetForegroundArgs[0] = Boolean.FALSE;
                invokeMethod(mSetForeground, mSetForegroundArgs);
            }
        }
    }
    private void openFile(File file) {
        // TODO Auto-generated method stub
        Log.i("OpenFile", file.getName());
        Log.i("OpenFile", file.getAbsolutePath());
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(android.content.Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file),
                "application/vnd.android.package-archive");
        startActivity(intent);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        /*记录退出时下载任务的状态-复原用*/
        for (DownInfo downInfo : listData) {
            dbUtil.update(downInfo);
        }
//        stopForegroundCompat(NOTIFICATION_ID);
    }
}
